package models;

import java.io.Serializable;
import javax.persistence.*;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * The persistent class for the msg database table.
 * 
 */
@Entity
@Table(name = "MSG")
public class Msg implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @TableGenerator(
            name = "MSG_SEQ",
            table = "SEQUENCE",
            pkColumnName = "NAME",
            pkColumnValue = "MSG_SEQ",
            valueColumnName = "CNT",
            initialValue = 10000,
            allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "MSG_SEQ")
    @Column(unique = true, nullable = false)
    private Integer id;

    @Column(name = "CONTENT_ID")
    private Integer contentId;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATE_D")
    private Date createD;

    @Column(name = "FROM_ADDR", length = 100)
    private String fromAddr;

    @Column(name = "FROM_AID")
    private Integer fromAid;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "SCHEDULED_D")
    private Date scheduledD;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "SENT_D")
    private Date sentD;

    private int status;

    private int transport;

    private String bcc;

    private String cc;

    private String error;

    @Column(name = "FROM_NAME")
    private String fromName;

    @Column(name = "REPLY_TO")
    private String replyTo;

    @Column(name = "TO_ADDR", length = 100)
    private String toAddr;

    @Column(name = "TO_AID")
    private Integer toAid;

    @Column(name = "TRY_COUNT")
    private int tryCount;

    private int type;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "UPDATE_D")
    private Date updateD;

    public Msg() {
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getContentId() {
        return this.contentId;
    }

    public void setContentId(Integer contentId) {
        this.contentId = contentId;
    }

    public Date getCreateD() {
        return this.createD;
    }

    public void setCreateD(Date createD) {
        this.createD = createD;
    }

    public String getFromAddr() {
        return this.fromAddr;
    }

    public void setFromAddr(String fromAddr) {
        this.fromAddr = fromAddr;
    }

    public Integer getFromAid() {
        return this.fromAid;
    }

    public void setFromAid(Integer fromAid) {
        this.fromAid = fromAid;
    }

    public Date getScheduledD() {
        return this.scheduledD;
    }

    public void setScheduledD(Date scheduledD) {
        this.scheduledD = scheduledD;
    }

    public Date getSentD() {
        return this.sentD;
    }

    public void setSentD(Date sentD) {
        this.sentD = sentD;
    }

    public Status getStatus() {
        return Status.values()[this.status];
    }

    public void setStatus(Status status) {
        this.status = status.ordinal();
    }

    public String getToAddr() {
        return this.toAddr;
    }

    public void setToAddr(String toAddr) {
        this.toAddr = toAddr;
    }

    public Integer getToAid() {
        return this.toAid;
    }

    public void setToAid(Integer toAid) {
        this.toAid = toAid;
    }

    public int getTryCount() {
        return this.tryCount;
    }

    public void setTryCount(int tryCount) {
        this.tryCount = tryCount;
    }

    public Type getType() {
        return Type.values()[this.type];
    }

    public void setType(Type type) {
        this.type = type.ordinal();
    }

    public Date getUpdateD() {
        return this.updateD;
    }

    public void setUpdateD(Date updateD) {
        this.updateD = updateD;
    }

    public Transport getTransport() {
        return Transport.values()[transport];
    }

    public void setTransport(Transport transport) {
        this.transport = transport.ordinal();
    }

    public String getBcc() {
        return bcc;
    }

    public void setBcc(String bcc) {
        this.bcc = bcc;
    }

    public String getCc() {
        return cc;
    }

    public void setCc(String cc) {
        this.cc = cc;
    }

    public String getFromName() {
        return fromName;
    }

    public void setFromName(String fromName) {
        this.fromName = fromName;
    }

    public String getReplyTo() {
        return replyTo;
    }

    public void setReplyTo(String replyTo) {
        this.replyTo = replyTo;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public static enum Type {
        ANY, // 0 - internal status to be used only by admin app
        NONE, // 1 - 
        INVITATION, // 2 -
        ALERT, // 3 - 
        ADMIN_ALERT, // 4 - 
        UNCRUNCH_INVITE, //5 
    }

    public static enum Transport {
        ANY, // 0 - internal status to be used only by admin app
        EMAIL, // 1 -
        SMS;// 2 - 
    }

    // ============================================================================
    // all non top link code and fields should go below this line

    // WARNING: do not change the order of the enum values. ordinal() MUST match
    // the constants in lc_sys and table value check constraints

    public static enum Status {
        ANY, // 0 - internal status to be used only by admin app
        PENDING, // 1 - waiting to be sent
        UNSUPPORTED_TRANSPORT, // 2 - unknown transport specified
        SENT, // 3 - message has been successfully sent
        ERROR(true), // 4 - error sending; further tries will be attempted
        ABORTED, // 5 - send of the message has been aborted
        USER_ON_DND, // 6 - the email has not been send, because the to address is on a "do not disturb" list
        DELAYED_SENDING, // 7 - there is a forced delay in sending the message, i.e. waiting for a forced time-out
        USER_OPTOUT, // 8 - user has opted out
        ;

        private boolean decRetry = false;

        private Status() {
            ;
        }

        private Status(boolean decReTry) {
            this.decRetry = decReTry;
        }

        public boolean decReTry() {
            return this.decRetry;
        }

        public boolean in(Status... statuss) {
            for (Status s : statuss)
                if (this == s)
                    return true;

            return false;
        }
    }

    public void appendError(String s) {
        StringBuilder errors = new StringBuilder("... ").append(SimpleDateFormat.getInstance().format(new Date()))
                .append(" - ").append(s).append("\n").append(error == null ? "" : error);

        this.error = errors.toString();
    }
}